package code;



import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 *
 * @author Mr. Butkus
 */

public class RealMachine {
	
	//---- Constants
	
public static final int RM_U_MEMORY_SIZE = 256 * 128;
public static final int RM_S_MEMORY_SIZE = 256 * 128;
public static final int Block_size = 256;

public FS fs;
private String currentlyOpenedFile;

	
	//---- Fields
	
	/* RM procesoriaus registrai */

        private Word PTR = new Word();              // 4B puslapiu lenteles registras -- naudojami 2
        private Word SS = new Word();               // 4B steko segmento registras
        private Word SP = new Word();               // 4B steko virsunes registras
        public Word IP = new Word();                // 4B virtualios masinos programu skaitiklis
        private boolean C = false;                  // 1B loginis trigeris
        private Word CS = new Word();               // 4B kodo segmento registras
        private Word DS = new Word();               // 4B duomenu segmento registras

	private char MODE = 'u';      // procesoriaus darbo rezimas
	private int PI = 0;           // programiniu pertraukimu registras
	private int SI = 0;           // supervizoriniu pertraukimu registras
	private int TI = 10;          // taimerio registras
	
	/* RM vidine atmintis */
	public Word[] memory = new Word[RM_U_MEMORY_SIZE + RM_S_MEMORY_SIZE];
	
	/* RM isorine atmintis */
	private String fileName = "";
	
	/* Ivedimo irenginys */
	public Vector input = new Vector();
	
	/* Isvedimo irenginys */
	public Vector output = new Vector();
    private File userProgramFile;
    int i; // for READ and WRIT only
	
	//---- Methods
	
	/**
	 * Constructor
	 */
	public RealMachine(FS fs) {
		for (int ii=0; ii<RM_U_MEMORY_SIZE+RM_S_MEMORY_SIZE; ii++) {
			this.memory[ii] = new Word();
		}
                this.fs = fs;
	}
	
 
        public Word[] getMemory()
        {
            return this.memory;
        }        
        
public void PU(int adr)
{
    //   if  (getSP() <= 8){
    setSP(getSP() + 1);
    // this.memory[getSS() + getSP()] = this.memory[adr];
    this.memory[getSS() + getSP()].a = this.memory[adr].a;
    this.memory[getSS() + getSP()].b = this.memory[adr].b;
    this.memory[getSS() + getSP()].c = this.memory[adr].c;
    this.memory[getSS() + getSP()].d = this.memory[adr].d;
//   } 
}

public void PO(int adr)
{
    if (getSP() > 0)
    {
      //  this.memory[adr] = this.memory[getSS() + getSP()];        //bad
        
                                                                    // 4 lines below -- good
        this.memory[adr].a = this.memory[getSS() + getSP()].a;
        this.memory[adr].b = this.memory[getSS() + getSP()].b;
        this.memory[adr].c = this.memory[getSS() + getSP()].c;
        this.memory[adr].d = this.memory[getSS() + getSP()].d;
        //   this.memory[getSS() + getSP()] = new Word();
        this.memory[getSS() + getSP()].a = intToHexWord(0).a;
        this.memory[getSS() + getSP()].b = intToHexWord(0).b;
        this.memory[getSS() + getSP()].c = intToHexWord(0).c;
        this.memory[getSS() + getSP()].d = intToHexWord(0).d;
        setSP(getSP() - 1);
    }
}

public void AD()
{
    int ii;
    if (getSP() >= 2)
    {
        ii = (this.wordToInt(memory[getSS() + getSP() - 1]) + this.wordToInt(this.memory[getSS() + getSP()]));
        this.memory[getSS() + getSP()] = new Word();
        setSP(getSP() - 1);
        this.memory[getSS() + getSP()] = this.intToDecWord(ii);
    }
}

public void SB()
{
    int ii;
    if (getSP() >= 2)
    {
        ii = (int) (this.wordToInt(memory[getSS() + getSP() - 1]) - this.wordToInt(this.memory[getSS() + getSP()]));
        //    this.memory[getSS() + getSP()] = new Word();
        this.memory[getSS() + getSP()].a = intToHexWord(0).a;
        this.memory[getSS() + getSP()].b = intToHexWord(0).b;
        this.memory[getSS() + getSP()].c = intToHexWord(0).c;
        this.memory[getSS() + getSP()].d = intToHexWord(0).d;
        setSP(getSP() - 1);
        this.memory[getSS() + getSP()] = this.intToDecWord(ii);
    }
}

public void MUL()
{
    int ii;
    if (getSP() >= 2)
    {
        ii = (int) (this.wordToInt(memory[getSS() + getSP() - 1]) * this.wordToInt(this.memory[getSS() + getSP()]));
        //    this.memory[getSS() + getSP()] = new Word();
        this.memory[getSS() + getSP()].a = intToHexWord(0).a;
        this.memory[getSS() + getSP()].b = intToHexWord(0).b;
        this.memory[getSS() + getSP()].c = intToHexWord(0).c;
        this.memory[getSS() + getSP()].d = intToHexWord(0).d;
        setSP(getSP() - 1);
        this.memory[getSS() + getSP()] = this.intToDecWord(ii);
    }
}

public void Compare()
{
    if (getSP() >= 2)
        if (wordToInt(this.memory[getSS() + getSP() - 1]) == wordToInt(this.memory[getSS() + getSP()]))
            this.setC(true);
        else
            this.setC(false);
}        

public int getUMFootprint()
{
    return RM_U_MEMORY_SIZE;
}

public int getSMFootprint()
{
    return RM_S_MEMORY_SIZE;
}

// REGISTRU SET'eriai ir GET'eriai
public int getPTR()                 //4B -- naudojami 2
{
    return hexToDec(wordToHexString(this.PTR));
}

public void setPTR(int pointer)
{
    this.PTR = intToHexWord(pointer);
}

public int getSS()                  // 4B steko segmento registras
{
    return hexToDec(wordToHexString(this.SS));
}

public void setSS(int pointer)
{
    this.SS = intToHexWord(pointer);
}

public int getSP()                  // 4B steko virsunes registras
{
    return hexToDec(wordToHexString(this.SP));
}

public void setSP(int pointer)
{
    this.SP = intToHexWord(pointer);
}

public int getIP()                  // 4B virtualios masinos programu skaitiklis
{
    if ((IP.a + IP.b + IP.c + IP.d) == 0)
        setIP(0);
    return hexToDec(wordToHexString(this.IP));
}

public void setIP(int pointer)
{
    this.IP = intToHexWord(pointer);
}

public boolean getC()               // 1B loginis trigeris
{
    return this.C;
}

public void setC(boolean c)
{
    this.C = c;
}

public int getCS()                  // 4B kodo segmento registras
{
    return hexToDec(wordToHexString(this.CS));
}

public void setCS(int pointer)
{
    this.CS = intToHexWord(pointer);
}

public int getDS()                 // 4B duomenu segmento registras
{
    return hexToDec(wordToHexString(this.DS));
}

public void setDS(int pointer)
{
    this.DS = intToHexWord(pointer);
}

public void setUserProgram(File file)
{
    userProgramFile = file;
}

public File getUserProgram()
{
    return this.userProgramFile;
}        
        
 	

	public void setMODE(char mode){
		this.MODE = mode;
	}

	public char getMODE(){
		return this.MODE;
	}
	

	public void setPI(int pi){
		this.PI = pi;
	}
	

	public int getPI(){
		return this.PI;
	}
	

	public void setSI(int si){
		this.SI = si;
	}
	

	public int getSI(){
		return this.SI;
	}
	

	public void setTI(int ti){
		this.TI = ti;
	}
	

	public int getTI(){
		return this.TI;
	}
	

	public void setMemory(short adr, char[] chr) {
		this.memory[adr].a = chr[0];
		this.memory[adr].b = chr[1];
		this.memory[adr].c = chr[2];
		this.memory[adr].d = chr[3];
	}
	
	public Vector getInput(){
		return this.input;
	}
	

	public Vector getOutput(){
		return this.output;
	}
	

	public void setOutput(Word out) {
		this.output.add(out);
	}
	

	public void setFile(String name) {
		this.fileName = name;
	}
	

	public String getFile() {
		return this.fileName;
	}
	



//  === KONVERTAVIMAI ===
public int wordToInt(Word w)
{
    int s = 0;
    s = Integer.valueOf(String.valueOf(w.a)) * 1000 + Integer.valueOf(String.valueOf(w.b)) * 100 + Integer.valueOf(String.valueOf(w.c)) * 10 + Integer.valueOf(String.valueOf(w.d));
    return s;
}

public String wordToHexString(Word w)
{
    String str = new String();
    str = String.valueOf(w.a) + String.valueOf(w.b) + String.valueOf(w.c) + String.valueOf(w.d);
    return str;
}

public Word intToDecWord(int s)
{
    Word w = new Word();
    s = s % 10000;
    w.a = Integer.toString(s / 1000).charAt(0);
    w.b = Integer.toString(s % 1000 / 100).charAt(0);
    w.c = Integer.toString(s % 100 / 10).charAt(0);
    w.d = Integer.toString(s % 10).charAt(0);
    return w;
}

public Word intToHexWord(int s)
{
    Word w = new Word();
    String hexString;
    hexString = Integer.toHexString(0x10000 | s).toUpperCase();
    w.a = hexString.charAt(1);
    w.b = hexString.charAt(2);
    w.c = hexString.charAt(3);
    w.d = hexString.charAt(4);
    return w;
}

public int hexToDec(String hex)
{
    int ii;
    ii = Integer.parseInt(hex, 16);
    return ii;
}

private String wordVectorToString(Vector wv)
{
    Vector vector = wv;
    String string = "";
    for (int ii = 0; ii < vector.size(); ii++)
    {
        string += wordToString((Word) vector.get(ii));
    }

    return string;
}

public String wordToString(Word w)
{
    char[] asdf = new char[4];
    asdf[0] = w.a;
    asdf[1] = w.b;
    asdf[2] = w.c;
    asdf[3] = w.d;
    return String.valueOf(asdf);
}

private Vector stringToWordVector(String str)
{
    Vector vector = new Vector();
    Word word[];
    char[] tmp = null;
    int length;
    int charsToAdd;     // string/4 must be = 0; cause word = 4 chars. this is to compensate.

    // makes string dividable by 4
    length = str.length();
    if (length % 4 > 0)
    {
        charsToAdd = 4 - (length % 4);
        for (int zz = 0; zz < charsToAdd; zz++)
        {
            str += String.valueOf(0);
        }
    }

    word = new Word[str.length() / 4];
    for (int aa = 0; aa < str.length() / 4; aa++)
    {
        word[aa] = new Word();
    }
    tmp = str.toCharArray();
    for (int g = 0; g < tmp.length / 4; g++)
    {
        // Jei priskytei idejai i Vektoriu elementa, po to ji pakeitai ir dar pridejai. turesi ne skirtingus, o vienodus elementus Vektoriuje.
        word[g].a = tmp[g * 4];
        word[g].b = tmp[g * 4 + 1];
        word[g].c = tmp[g * 4 + 2];
        word[g].d = tmp[g * 4 + 3];
        vector.add(word[g]);
    }
    return vector;
}

public void printMem()
{
    
    for(int zz = 0; zz < RealMachine.Block_size * 7; zz++)
    {
        if(!(FS.wordEmpty(memory[zz])))
                System.out.println("RAM "+zz+" "+ wordToHexString(memory[zz]).toString()+"|");
    }
}

//  === End of KONVERTAVIMAI ===


public void allocateMemory()
{
    int k = 0;
    //  if (size <= 1) size = 2;
    int[] tmp = new int[VirtualMachine.VM_MEMORY_SIZE / Block_size];    //bloku numeriai
    boolean bool = false;

    //pirma pasiimam lentele
    Vector memoryUsageTable = new Vector();

    if (!getUsedMemory().isEmpty())
        memoryUsageTable.addAll(getUsedMemory());

    //skaidom RM atminti blokais po 10 zodziu
    for (int e = 0; e < (RM_U_MEMORY_SIZE / Block_size); e++)
    {
        bool = true;
        //tikrinam ar blokas neuzimtas
        for (int j = 0; j < memoryUsageTable.size(); j++)
        {
            //perziurim ar i nesutampa ne su vienu uzimtos atm bloko nr
            if (Integer.parseInt((memoryUsageTable.get(j)).toString()) == e)
                bool = false;
        }
        if (bool && k < VirtualMachine.VM_MEMORY_SIZE / Block_size)
        {
            tmp[k] = e;
            k++;
        }
    }
    //jei rasta tiek, kiek reikia laisvu bloku
    //if (k == VirtualMachine.VM_MEMORY_SIZE /Block_size ){ 
    if (tmp.length == VirtualMachine.VM_MEMORY_SIZE / Block_size)
    {
        setUsedMemory(tmp);
        createPagesTable(tmp);
        createStack();
        setCS(0);
        setDS((VirtualMachine.VM_MEMORY_SIZE / 2));
    }

}
	
	/**
	 * Sukuriam puslapiu lentele
	 * @param tmp
	 */
private void createPagesTable(int[] tmp)
{
    int x = 0;		 //puslapiu lenteles bloko nr
    boolean bool = true;     //ar blokas tuscias
    boolean testi = true;    //ar testi paieska puslapiu lenteles vietai
    int[] tableAdr = new int[1];

    //pirma pasiimam lentele
    Vector memoryUsageTable = new Vector();

    if (!getUsedMemory().isEmpty())
        memoryUsageTable.addAll(getUsedMemory());

    //skaidom RM atminti blokais po 10 zodziu
    for (int e = 0; e < RM_U_MEMORY_SIZE / Block_size; e++)
    {
        bool = true;
        //tikrinam ar blokas tuscias ir ar dar nepaskirtas VM
        for (int j = 0; j < memoryUsageTable.size(); j++)
        {
            //perziurim ar i nesutampa ne su vienu uzimtos atm bloko nr
            if (Integer.parseInt((memoryUsageTable.get(j)).toString()) == e)
                bool = false;
        }
        //jei rastas tuscias blokas
        if (bool && testi)
        {
            x = e;
            testi = false;

            for (int k = 0; k < tmp.length; k++)
            {
                //puslapiu lentele uzpildom isskirtu takeliu adresais
                memory[x * Block_size + k].a = intToHexWord(tmp[k]).a;
                memory[x * Block_size + k].b = intToHexWord(tmp[k]).b;
                memory[x * Block_size + k].c = intToHexWord(tmp[k]).c;
                memory[x * Block_size + k].d = intToHexWord(tmp[k]).d;
            }
            setPTR(x); // nustatom PTR registro reiksme, kuri rodo i puslapiu lentele
            tableAdr[0] = x;
            setUsedMemory(tableAdr);
        }
    }
}

private void createStack()
{
    int x = 0;               //steko bloko numeris
    boolean bool = true;     //ar blokas tuscias
    boolean testi = true;    //ar testi paieska puslapiu lenteles vietai

    //pirma pasiimam lentele
    Vector memoryUsageTable = new Vector();

    if (!getUsedMemory().isEmpty())
        memoryUsageTable.addAll(getUsedMemory());

    //skaidom RM atminti blokais po 10 zodziu
    for (int b = 0; b < RM_U_MEMORY_SIZE / Block_size; b++)
    {
        bool = true;
        //tikrinam ar blokas tuscias ir ar dar nepaskirtas VM
        for (int j = 0; j < memoryUsageTable.size(); j++)
        {
            //perziurim ar i nesutampa ne su vienu uzimtos atm bloko nr
            if (Integer.parseInt((memoryUsageTable.get(j)).toString()) == b)
                bool = false;
        }
        //jei rastas tuscias blokas
        if (bool && testi)
        {
            x = b;
            testi = false;

            /*	for (int k=0; k<10; k++) {
            //puslapiu lentele uzpildom isskirtu 10 takeliu adresais
            memory[x * 10 + k].a = shortToWord(a).a;    
            memory[x * 10 + k].b = shortToWord(a).b;
            memory[x * 10 + k].c = shortToWord(a).c;
            memory[x * 10 + k].d = shortToWord(a).d;
            }*/

            //kreivos rankos!
            memory[RM_U_MEMORY_SIZE + b].a = intToHexWord(x).a;
            memory[RM_U_MEMORY_SIZE + b].b = intToHexWord(x).b;
            memory[RM_U_MEMORY_SIZE + b].c = intToHexWord(x).c;
            memory[RM_U_MEMORY_SIZE + b].d = intToHexWord(x).d;

            this.setSS(x * Block_size);     // nustatom SS registro reiksme, kuri rodo i steko segmenta
            //  this.SP = -1;                           
            setSP(0);  // db bus ne nuo 0-inio SS zodzio, o nuo 1-ojo, nes int -1 = 65535

        }
    }
}
	
	/**
	 * Is virtualaus adreso gaunam realu atminties adresa
	 * @param x1
	 * @param x2
	 * @return address
	 */
        
    public int getRealAddress(int adr)
    {
        int blNr, woNr;

        blNr = adr / 256;
        woNr = adr % 256;

        Word word = memory[getPTR() * Block_size + blNr];
        
        return wordToInt(word) * Block_size + woNr;
    }

//	public short getRealAddress(int x1, int x2){
//		short a2 = 0, a3 = 0;
//	
//		//is ptr pasiimam a2 ir a3
//		a2 = (short)(this.PTR / 10);
//		a3 = (short)(this.PTR % 10);
//		return (short)(10 * wordToShort(memory[10 * (10 * a2 + a3) + x1]) + x2);
//	}
	
	

private void setUsedMemory(int[] tmp)
{

    // Eina nuo SU pradzios ir iesko pirmo neuzimto zodzio

    int notAllocatedYet = 0;
    int value = 0;
    value = memory[RM_U_MEMORY_SIZE].a * 1000 + memory[RM_U_MEMORY_SIZE].b * 100 + memory[RM_U_MEMORY_SIZE].c * 10 + memory[RM_U_MEMORY_SIZE].d;

    while (value != 0)
    {
        notAllocatedYet++;
        value = memory[RM_U_MEMORY_SIZE + notAllocatedYet].a * 1000 + memory[RM_U_MEMORY_SIZE + notAllocatedYet].b * 100 + memory[RM_U_MEMORY_SIZE + notAllocatedYet].c * 10 + memory[RM_U_MEMORY_SIZE + notAllocatedYet].d;
    }
    // =====
    // iejome i neuzimtu zodziu zona    
    for (int ii = notAllocatedYet; ii < tmp.length + notAllocatedYet; ii++)
    {
        //naudojamos atminties lentele uzpildom puslapiu adresais
        //butkus -- kala i SU pradzia, nes vis vien kol kas tik viena VM dirba?
        //butkus -- su notAllocatedYet jau nebe i pradzia, o nuo... nu normaliai
        memory[RM_U_MEMORY_SIZE + ii].a = intToHexWord(tmp[ii - notAllocatedYet]).a;
        memory[RM_U_MEMORY_SIZE + ii].b = intToHexWord(tmp[ii - notAllocatedYet]).b;
        memory[RM_U_MEMORY_SIZE + ii].c = intToHexWord(tmp[ii - notAllocatedYet]).c;
        memory[RM_U_MEMORY_SIZE + ii].d = intToHexWord(tmp[ii - notAllocatedYet]).d;
    }
}

	
	private Vector getUsedMemory() {
		Vector tmp = new Vector();
		int ii=0;
		int value=0;
		
		//patikrinam ar pirmas zodis ne nulis
		value = memory[RM_U_MEMORY_SIZE].a*1000 + memory[RM_U_MEMORY_SIZE].b*100 + memory[RM_U_MEMORY_SIZE].c*10 + memory[RM_U_MEMORY_SIZE].d;
		
		while (value != 0) {
			tmp.addElement(wordToInt(memory[RM_U_MEMORY_SIZE + ii]));
			ii++;
			value = memory[RM_U_MEMORY_SIZE+ii].a*1000 + memory[RM_U_MEMORY_SIZE+ii].b*100 + memory[RM_U_MEMORY_SIZE+ii].c*10 + memory[RM_U_MEMORY_SIZE+ii].d;
		}
		return tmp;
	}
	

        
void executeCommands(OPC opc, int operand) throws IOException
{
    int adr = 0;
    int realAdr = 0;

    adr = (getDS() + operand);
  //  realAdr = wordToInt(memory[getPTR() * 256]) + adr;
    realAdr = getRealAddress(adr);

    Vector fn = new Vector();
    String filename;
    Vector vec = new Vector();
    Vector readWriteStream = new Vector();
    boolean continueScaningStream = true;
    Word EOFsymbol = new Word();
    EOFsymbol.a = ' ';
    EOFsymbol.b = ' ';
    EOFsymbol.c = ' ';
    EOFsymbol.d = '$';

    switch (opc)
    {
        case PUSH:
            PU(realAdr);
            setIP((getIP() + 2));
            TI--;
            break;
        case POP_:
            PO(realAdr);
            setIP((getIP() + 2));
            TI--;
            break;
        case ADD_:
            AD();
            setIP((getIP() + 2));
            TI--;
            break;
        case SUB_:
            SB();
            setIP((getIP() + 2));
            TI--;
            break;
        case MUL_:
            MUL();
            setIP((getIP() + 2));
            TI--;
            break;
        case CMP_:
            Compare();
            setIP((getIP() + 2));
            TI--;
            break;
        case JMPT:
            if (getC() == true)
                //   setIP(wordToShort(memory[realAdr]));
                setIP(operand);
            else
                setIP((getIP() + 2));
            
            TI--;
            break;
            
            //GD__ yra be TI-- and stuff.
        case GD__:

            //nuskaitom 10 zodziu is ivedimo srauto ir irasom i ATM[x*]
            if (!input.isEmpty())
            {
                    int nr=0;
                    for (int e=0; e<10; e++) {
                            if (e < ((String)input.firstElement()).length() && nr < ((String)input.firstElement()).length()) {
                                    if (nr < ((String)input.firstElement()).length()) {
                                            memory[realAdr + e].a = ((String)input.firstElement()).charAt(nr);
                                            nr++;
                                    } else {
                                            memory[realAdr + e].a = ' ';
                                    }
                                    if (nr < ((String)input.firstElement()).length()) {
                                            memory[realAdr + e].b = ((String)input.firstElement()).charAt(nr);
                                            nr++;
                                    } else {
                                            memory[realAdr + e].b = ' ';
                                    }
                                    if (nr < ((String)input.firstElement()).length()) {
                                            memory[realAdr + e].c = ((String)input.firstElement()).charAt(nr);
                                            nr++;
                                    } else {
                                            memory[realAdr + e].c = ' ';
                                    }
                                    if (nr < ((String)input.firstElement()).length()) {
                                            memory[realAdr + e].d = ((String)input.firstElement()).charAt(nr);
                                            nr++;
                                    } else {
                                            memory[realAdr + e].d = ' ';
                                    }
                            }
                    }
                    input.removeElement(input.firstElement());
                    setIP(getIP()+2);
                    TI--;
            } else SI = 1;
            break;
        case PUT_:
            for (int ii = 0; ii < 10; ii++)
            {
                output.add(memory[realAdr + ii]);
            }
            setIP((getIP() + 2));
            TI--;
            break;
        case JMPF:
            if (!getC())
                setIP(operand);
            else
                setIP((getIP() + 2));
            TI--;
            break;
        case JMP_:
            setIP(operand);
            TI--;
            break;


        //////// LameFS commands
        case CREA:
            // get filename from nurodytas adresas
            // create
            fn.clear();

            for (int z = 0; z < 3; z++)
            {
                fn.add(memory[realAdr + z]);
            }
            filename = wordVectorToString(fn);

            fs.createFile(filename, 1);
            setIP((getIP() + 2));
            TI--;
            break;
        case DELE:
            // get filename from nurodytas adresas
            //      if not closed, will not work, close first
            // delete
            
            fn.clear();

            for (int z = 0; z < 3; z++)
            {
                fn.add(memory[realAdr + z]);
            }
            filename = wordVectorToString(fn);

            fs.deleteFile(filename);
            setIP((getIP() + 2));
            TI--;
            break;
        case OPEN:
            // get filename from nurodytas adresas
            // open
            fn.clear();

            for (int z = 0; z < 3; z++)
            {
                fn.add(memory[realAdr + z]);
            }
            filename = wordVectorToString(fn);

            fs.open(filename);
            currentlyOpenedFile = filename;
            setIP((getIP() + 2));
            TI--;
            break;
        case CLOS:
            // get filename from nurodytas adresas
            // close

            fn.clear();

            for (int z = 0; z < 3; z++)
            {
                fn.add(memory[realAdr + z]);
            }
            filename = wordVectorToString(fn);

            fs.close(filename);
            currentlyOpenedFile = null;
            
            setIP((getIP() + 2));
            TI--;
            break;
        case READ:
            // get destination from nurodytas adresas
            //      file must be already opened
            // read

            vec.clear();

            for (int z = 0; z < 3; z++)
            {
                fn.add(memory[realAdr + z]);
            }
            filename = wordVectorToString(fn);

            vec = fs.read(currentlyOpenedFile);

            for (int z = 0; z < vec.size(); z++)
            {
                memory[realAdr + z] = (Word) vec.get(z);
            }
            setIP((getIP() + 2));
            TI--;

            break;
        case WRIT:
            // get source from nurodytas adresas
            //      file must be already opened
            // write

            vec.clear();
            continueScaningStream = true;
            i = 0;

            while (continueScaningStream)
            {
                if (memory[realAdr + i].d == EOFsymbol.d)
                    continueScaningStream = false;
                else
                {
                    vec.add(memory[realAdr + i]);
                    i++;
                }
            }
            fs.write(currentlyOpenedFile, vec);

            setIP((getIP() + 2));
            TI--;
            break;
            
        case HALT:
               SI = 3;
                setIP((getIP() + 2));
                TI--;
            break;
    }
    
    
    

}        
        
//	public void executeCommands(short opc) {
//		short adr = 0;
//		short realAdr = 0;
//		
//		int opCode = opc / 100;
//		int x = opc % 100 / 10;
//		int y = opc % 10;
//		
//		adr = (short)(x * 10 + y);
//		realAdr = (short)(50 + getRealAddress(adr / 10, adr % 10));
//		
//		switch(opCode) {
//			case 10:
//				//NO
//				//nieko nedaranti komanda
//				IP = (short)(IP+1);
//				TI--;
//				break;
//			case 11:
//				//LR
//				//uzkraunam R is ATM[xy]
//				R = wordToShort(memory[realAdr]);
//				IP = (short)(IP+1);
//				TI--;
//				break;
//			case 12:
//				//SR
//				//registra R isgaugom i ATM[xy]
//				memory[realAdr] = shortToWord(R);
//				IP = (short)(IP+1);
//				TI--;
//				break;
//			case 13:
//				//AD
//				//prie R pridedam ATM[xy]
//				R = (short)(R + wordToShort(memory[realAdr]));
//				IP = (short)(IP+1);
//				TI--;
//				break;
//			case 14:
//				//CR
//				if (R == wordToShort(memory[realAdr])) C = true;
//				else C = false;
//				IP = (short)(IP+1);
//				TI--;
//				break;
//			case 15:
//				//BT
//				if (C == true) IP = (wordToShort(memory[realAdr]));
//				else IP = (short)(IP+1);
//				TI--;
//				break;
//			case 16:
//				//NT
//				if (!C) IP = (short)(x * 10 + y);
//				else IP = (short)(IP+1);
//				TI--;
//				break;
//			case 17:
//				//GO
//				IP = (short)(x * 10 + y);
//				TI--;
//				break;
//			case 18:
//				//GD
//				//nuskaitom 10 zodziu is ivedimo srauto ir irasom i ATM[x*]
//				if (!input.isEmpty()) {
//					int nr=0;
//					for (int i=0; i<10; i++) {
//						if (i < ((String)input.firstElement()).length() && nr < ((String)input.firstElement()).length()) {
//							if (nr < ((String)input.firstElement()).length()) {
//								memory[realAdr + i].a = ((String)input.firstElement()).charAt(nr);
//								nr++;
//							} else {
//								memory[realAdr + i].a = ' ';
//							}
//							if (nr < ((String)input.firstElement()).length()) {
//								memory[realAdr + i].b = ((String)input.firstElement()).charAt(nr);
//								nr++;
//							} else {
//								memory[realAdr + i].b = ' ';
//							}
//							if (nr < ((String)input.firstElement()).length()) {
//								memory[realAdr + i].c = ((String)input.firstElement()).charAt(nr);
//								nr++;
//							} else {
//								memory[realAdr + i].c = ' ';
//							}
//							if (nr < ((String)input.firstElement()).length()) {
//								memory[realAdr + i].d = ((String)input.firstElement()).charAt(nr);
//								nr++;
//							} else {
//								memory[realAdr + i].d = ' ';
//							}
//						}
//					}
//					input.removeElement(input.firstElement());
//					IP = (short)(IP+1);
//					TI--;
//				} else SI = 1;
//				break;
//			case 19:
//				//PD
//				//SI = 2;
//				//irasom 10 ATM[x*] zodziu i isvedimo srauta
//				for (int i=0; i<10; i++) output.add(memory[realAdr + i]);
//				IP = (short)(IP+1);
//				TI--;
//				break;
//			case 20:
//				//HL
//				SI = 3;
//				IP = (short)(IP+1);
//				TI--;
//		}
//	}
}
